package gps.monitor.common.tools.network;

import gps.monitor.common.core.network.ISocketClient;
import gps.monitor.common.core.network.NetworkException;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

/**
 * @author cyq
 * @date 2021/11/4
 * @desc talk is cheep,show me the code
 */
public final class SimpleNettyClient implements ISocketClient {

    private SimpleNettyConnectConfig connectionConfig;

    private EventLoopGroup workerGroup;

    private ChannelHandler encoder;

    private ChannelFuture work;

    protected SimpleNettyClient(SimpleNettyConnectConfig config, ChannelHandler encoder) {
        this.connectionConfig = config;
        this.encoder = encoder;
    }

    public void connet() throws NetworkException {

        if (connectionConfig == null) throw new NetworkException("缺少配置：SimpleNettyConnectConfig");

        workerGroup = new NioEventLoopGroup();

        try {

            //1.创建服务器对象
            Bootstrap bootstrap = new Bootstrap();
            //2.配置参数
            bootstrap.group(workerGroup)
                    //主线程处理类，底层用的是反射
                    .channel(NioSocketChannel.class)
                    //子线程处理类
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();
                            //pipeline.addLast(new HttpClientCodec());
                            //pipeline.addLast(new HttpObjectAggregator(65536));
                            pipeline.addLast(encoder);
                        }
                    });

            //3.启动服务器
            work = bootstrap.connect(connectionConfig.getRemoteAddress(),connectionConfig.getRemotePort()).sync();
            //f.channel().closeFuture();
        }catch (Exception e){
            e.printStackTrace();
            throw new NetworkException(e);
        }finally {
            System.out.println("Client连接成功");
        }
    }

    public void disconnect() throws NetworkException {

        if (workerGroup == null) return;

        work.channel().close();
        //关闭线程池
        workerGroup.shutdownGracefully();
    }

    public boolean write(CharSequence data) throws NetworkException {
        if (work == null) throw new NetworkException("client未初始化");
        work.channel().writeAndFlush(data);
        return false;
    }
}
